<?php
declare(strict_types=1);
/**
 * This file is part of EasySwoole.
 *
 * @link     https://www.easyswoole.com
 * @document https://www.easyswoole.com
 * @contact  https://www.easyswoole.com/Preface/contact.html
 * @license  https://github.com/easy-swoole/easyswoole/blob/3.x/LICENSE
 */

namespace App\Dao;

use App\Enums\DataScopeEnum;
use App\Model\DeptModel;
use App\Model\JobModel;
use App\Model\RoleModel;
use App\Model\UserModel;
use EasySwoole\Mysqli\QueryBuilder;
use EasySwoole\ORM\Db\MysqliClient;
use EasySwoole\ORM\DbManager;

class UserDao extends BaseDao
{
    protected function setModel(): string
    {
        return UserModel::class;
    }

    public function findByUsername(string $username)
    {
        $fields   = [
            'u.*',
            //            'u.password user_password, u.isAdmin user_is_admin',
            //            'u.userId as user_user_id, u.deptId as user_dept_id, u.username as user_username',
            //            'u.nickName as user_nick_name, u.email as user_email, u.phone as user_phone',
            //            'u.gender as user_gender, u.avatarName as user_avatar_name, u.avatarPath as user_avatar_path',
            //            'u.enabled as user_enabled, u.pwdResetTime as user_pwd_reset_time, u.createBy as user_create_by',
            //            'u.updateBy as user_update_by, u.createTime as user_create_time, u.updateTime as user_update_time',
            'd.deptId as dept_id, d.name as dept_name'
        ];
        $fieldStr = join(',', $fields);

        $builder = new QueryBuilder();
        $builder
            ->fields($fieldStr)
            ->where('u.username', $username)
            ->join('sys_dept d', 'u.deptId = d.deptId', 'LEFT')
            ->get('sys_user u');
        $res = DbManager::getInstance()->invoke(function (MysqliClient $client) use ($builder) {
            return $client->query($builder)->getResultOne();
        });

        $result = $res ?: [];

        $deptId   = 0;
        $deptName = '';
        if ($result) {
            $deptId   = $result['dept_id'];
            $deptName = $result['dept_name'];
            unset($result['deptId']);
            unset($result['dept_id']);
            unset($result['dept_name']);
        }

        $model = new UserModel($result);

        if ($result) {
            $model->setAttr('id', $model->userId);
            // dept
            $dept = [
                'id'   => $deptId,
                'name' => $deptName,
            ];
            $model->setAttr('dept', $dept);

            // jobs
            /** @var UserJobDao $userJobDao */
            $userJobDao = app(UserJobDao::class);
            /** @var JobModel[] $jobList */
            $jobList = $userJobDao->findByUserId($model->userId);
            $jobs    = [];
            foreach ($jobList as $job) {
                $jobs[] = [
                    'id'   => $job->jobId,
                    'name' => $job->name,
                ];
            }
            $model->setAttr('jobs', $jobs);

            // roles
            /** @var UserRoleDao $userRoleDao */
            $userRoleDao = app(UserRoleDao::class);
            /** @var RoleModel[] $roleList */
            $roleList = $userRoleDao->findByUserId($model->userId);
            $roles    = [];
            foreach ($roleList as $role) {
                $roles[] = [
                    'dataScope' => $role->dataScope,
                    'id'        => $role->roleId,
                    'level'     => $role->level,
                    'name'      => $role->name,
                ];
            }
            $model->setAttr('roles', $roles);
        }

        return $model;
    }

    public function findByEmail(string $email)
    {
        return $this->getOne(['email' => $email]);
    }

    public function findByPhone(string $phone)
    {
        return $this->getOne(['phone' => $phone]);
    }
}
